import fs, { existsSync, mkdirSync } from 'fs'
import { join, parse, resolve } from 'path'

import fg from 'fast-glob'
import MarkdownIt from 'markdown-it'
import type { ComponentMeta, MetaCheckerOptions } from 'vue-component-meta'
import { createComponentMetaChecker } from 'vue-component-meta'

const md = new MarkdownIt()

export interface ComponentApiProps {
  name: ComponentMeta['props'][number]['name']
  description: ComponentMeta['props'][number]['description']
  // required: ComponentMeta['props'][number]['required']
  type: ComponentMeta['props'][number]['type']
  default: ComponentMeta['props'][number]['default']
}

export interface ComponentApi {
  props: ComponentApiProps[]
  events: ComponentMeta['events']
  slots: ComponentMeta['slots']
}

const checkerOptions: MetaCheckerOptions = {
  forceUseTs: true,
  schema: { ignore: ['MyIgnoredNestedProps'] },
  printer: { newLine: 1 },
}

const tsconfigChecker = createComponentMetaChecker(
  resolve(__dirname, '../tsconfig.json'),
  checkerOptions,
)

const filterMeta = (meta: ComponentMeta): ComponentApi => {
  // console.log('meta', meta.props)

  const props: ComponentApiProps[] = []
  try {
    meta.props.forEach((prop) => {
      if (prop.global) return

      const { name, description, required, type, default: defaultValue } = prop
      // console.log(`output->default`, typeof defaultValue)
      // console.log(`output->default`, defaultValue)

      props.push({
        name: `${name}${required ? '' : '?'}`,
        description: md.render(description),
        // required,
        type,
        default: defaultValue || 'unknown',
      })
    })
  } catch (error) {}

  return {
    props,
    events: meta.events,
    slots: meta.slots,
  }
}

const filterMetaChildren = (meta: ComponentMeta): ComponentApi => {
  // console.log('meta', meta.props)

  const props: ComponentApiProps[] = []
  meta.props.forEach((prop) => {
    if (prop.global) return

    const { name, description, required, type, default: defaultValue } = prop
    // console.log(`output->default`, typeof defaultValue)
    // console.log(`output->default`, defaultValue)

    props.push({
      name: `${name}${required ? '' : '?'}`,
      description: md.render(description),
      // required,
      type,
      default: defaultValue || 'unknown',
    })
  })

  return {
    props,
    events: meta.events,
    slots: meta.slots,
  }
}

// 获取类型文件
const components = fg.sync(['src/components/**/src/types.ts'], {
  cwd: resolve(__dirname, '../packages/zlyun-vue'),
  absolute: true,
})

// 获取次级类型文件
const componentsChildren = fg.sync(['src/components/**/src/config.ts'], {
  cwd: resolve(__dirname, '../packages/zlyun-vue'),
  absolute: true,
})
// console.log(11111111111111111111111111)

// 生成组件元数据
components.forEach((componentPath) => {
  // 将 'echarts-3d-pie' 转换成 'Echarts3dPie' 的格式 来生成组件json
  let componentExportName = componentPath
    .split('components/')[1]
    .split('/src')[0]
  componentExportName = componentExportName.replace(
    /([\\w\-])([a-z,0-9])/g,
    function (match, $1, $2, index, s) {
      let res = ''
      if ($1 == '-') {
        res = s[index + 1].toLocaleUpperCase()
      } else {
        res = $1 + $2
      }
      return res
    },
  )
  componentExportName = componentExportName.replace(
    /^([a-z])/g,
    function (match, $1, index, s) {
      return $1.toLocaleUpperCase()
    },
  )

  // console.log('componentExportName', `${componentExportName}Props`)

  const meta = filterMeta(
    tsconfigChecker.getComponentMeta(
      componentPath,
      `${componentExportName}Props`,
    ),
  )
  const metaDirPath = resolve(__dirname, '../packages/zlyun-vue/component-meta')

  if (!existsSync(metaDirPath)) mkdirSync(metaDirPath)

  const metaJsonFilePath = join(metaDirPath, `${componentExportName}.json`)
  fs.writeFileSync(metaJsonFilePath, JSON.stringify(meta, null, 4))
})
